package com.hu.bgp.framework;

import java.util.ArrayList;
import java.util.Observable;

import com.google.gwt.user.client.rpc.SerializationException;
import com.google.gwt.user.server.rpc.RPC;
import com.hu.bgp.exceptions.BgpServerException;

import com.hu.bgp.framework.clientapi.ClientToServerMessage;
import com.hu.bgp.framework.clientapi.GameOwnerMessage;
import com.hu.bgp.framework.clientapi.ServerToClientMessage;
import com.hu.bgp.framework.GameContext;

/**
 * Implementeer een subklasse van deze klasse bij het schrijven van de
 * game-logica van een spelletje.
 * 
 * @author ejvos
 */
public abstract class Server extends Observable implements ServerFacade
{
	private String GUID = null;
	private GameContext gameContext;
	// TODO debug.. default state is not RUNNING but initialing
	private GameState state = GameState.running;
	protected ArrayList<Player> players = new ArrayList<Player>();

	public Server(GameContext gameContext)
	{
		this.gameContext = gameContext;
	}

	public void setGUID(String GUID)
	{
		if (this.GUID == null)
			this.GUID = GUID;
		else
			throw new BgpServerException("GUID can only be assigned once!");
	}

	public String getGUID()
	{
		return GUID;
	}

	public void dispathMessage(ClientToServerMessage message)
	{
		if (message instanceof GameOwnerMessage)
		{
			switch (((GameOwnerMessage) message).getNewGameState())
			{
				case waitingforplayers:
					state = GameState.waitingforplayers;
					break;

				default:
					break;
			}
			setChanged();
			notifyObservers(state);
		}
		else
			handleMessage(message);
	}

	// Let the implementing sub class handle the messge
	public abstract void handleMessage(ClientToServerMessage message);

	public void broadcastMessage(ServerToClientMessage message)
	{
		gameContext.broadCastMessage(serializePayload(message));
	}

	public void addGameStateListener(GameStateListener listener)
	{
		addObserver(listener);

	}

	public GameContext getGameContext()
	{
		return gameContext;
	}

	public GameState getGameState()
	{
		return state;
	}

	public final int HashCode()
	{
		return super.hashCode();
	}

	// GWT serialzation stuff
	public String serializePayload(ServerToClientMessage message)
	{
		// TODO TEST with raw serialization
		String ret = "";
		try
		{
			java.lang.reflect.Method x;
			x = com.hu.bgp.framework.clientapi.BoardGameService.class.getMethod("sendMessage_dummy", null);
			ret = RPC.encodeResponseForSuccess(x, message);
		}
		catch (SecurityException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		catch (NoSuchMethodException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		catch (SerializationException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return ret;
	}

}
